#include "LineChartItem.h"
#include <QSGGeometry>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QDebug>
#include <cmath>

// === 全局变量：坐标轴样式 ===
static const QColor AXIS_COLOR = Qt::black;
static const int AXIS_WIDTH = 2;

// === 全局变量：网格样式 ===
static const QColor GRID_COLOR = QColor(200, 200, 255);
static const int GRID_SPACING = 1;
static const int GRID_WIDTH = 1;

// === 全局变量：折线样式 ===
static const QColor LINE_COLORS[] = {Qt::green, Qt::red, Qt::blue, Qt::magenta, Qt::cyan, Qt::yellow};
static const int LINE_WIDTH = 3; // 线宽

LineChartItem::LineChartItem(QQuickItem* parent)
    : QQuickItem(parent), m_scaleX(100.0), m_scaleY(100.0), m_offsetX(50), m_offsetY(50)
{
    setFlag(ItemHasContents, true);
    setAcceptedMouseButtons(Qt::LeftButton);
    setAcceptHoverEvents(true);
}

void LineChartItem::setData(const QVector<QPointF>& points) {
    m_series.clear();
    m_series.append(points);
    update();
}

void LineChartItem::setSeries(const QVector<QVector<QPointF>>& series) {
    m_series = series;
    update();
}

// ==== 绘制 ====
QSGNode* LineChartItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) {
    if (oldNode) {
        delete oldNode;
    }

    QSGNode* root = new QSGNode();

    // 网格
    root->appendChildNode(createGridNode());

    // 坐标轴
    root->appendChildNode(createAxisNode());

    // 折线：每条系列单独绘制
    for (int s = 0; s < m_series.size(); ++s) {
        const auto& points = m_series[s];
        if (points.size() < 2) continue;

        QColor color = LINE_COLORS[s % (sizeof(LINE_COLORS) / sizeof(QColor))];

        // 创建一个 Geometry 节点，包含所有线段
        int numSegments = points.size() - 1;
        QSGGeometry* geom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), numSegments * 2);
        geom->setDrawingMode(QSGGeometry::DrawLines);
        geom->setLineWidth(LINE_WIDTH); // 设置线宽

        QSGGeometry::Point2D* vertices = geom->vertexDataAsPoint2D();
        int idx = 0;

        for (int i = 0; i < points.size() - 1; ++i) {
            QPointF p1((points[i].x() * m_scaleX) + m_offsetX,
                       height() - m_offsetY - points[i].y() * m_scaleY);
            QPointF p2((points[i+1].x() * m_scaleX) + m_offsetX,
                       height() - m_offsetY - points[i+1].y() * m_scaleY);

            vertices[idx].x = p1.x();
            vertices[idx].y = p1.y();
            idx++;

            vertices[idx].x = p2.x();
            vertices[idx].y = p2.y();
            idx++;
        }

        auto mat = new QSGFlatColorMaterial();
        mat->setColor(color);

        auto node = new QSGGeometryNode();
        node->setGeometry(geom);
        node->setFlag(QSGNode::OwnsGeometry);
        node->setMaterial(mat);
        node->setFlag(QSGNode::OwnsMaterial);

        root->appendChildNode(node);
    }

    return root;
}

// ==== 网格 ====
QSGNode* LineChartItem::createGridNode() {
    QVector<QLineF> lines;

    qreal scaledSpacingX = GRID_SPACING * m_scaleX;
    qreal scaledSpacingY = GRID_SPACING * m_scaleY;

    // X 方向竖线
    for (qreal x = m_offsetX + scaledSpacingX; x <= width(); x += scaledSpacingX) {
        lines.append(QLineF(x, 0, x, height()));
    }

    // Y 方向横线
    qreal originY = height() - m_offsetY;

    // 向上
    for (int j = 0; originY - j * scaledSpacingY >= 0; ++j) {
        qreal y = originY - j * scaledSpacingY;
        lines.append(QLineF(m_offsetX, y, width(), y));
    }

    // 向下
    for (int j = 1; originY + j * scaledSpacingY <= height(); ++j) {
        qreal y = originY + j * scaledSpacingY;
        lines.append(QLineF(m_offsetX, y, width(), y));
    }

    QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), lines.size() * 2);
    geometry->setDrawingMode(QSGGeometry::DrawLines);
    geometry->setLineWidth(GRID_WIDTH);

    QSGGeometry::Point2D* vertices = geometry->vertexDataAsPoint2D();
    int idx = 0;
    for (const auto& line : lines) {
        vertices[idx].x = line.x1(); vertices[idx].y = line.y1(); idx++;
        vertices[idx].x = line.x2(); vertices[idx].y = line.y2(); idx++;
    }

    auto material = new QSGFlatColorMaterial();
    material->setColor(GRID_COLOR);

    auto node = new QSGGeometryNode();
    node->setGeometry(geometry);
    node->setFlag(QSGNode::OwnsGeometry);
    node->setMaterial(material);
    node->setFlag(QSGNode::OwnsMaterial);
    return node;
}

// ==== 坐标轴 ====
QSGNode* LineChartItem::createAxisNode() {
    QSGNode* root = new QSGNode();
    qreal originY = height() - m_offsetY;

    // X 轴（水平）
    {
        QSGGeometry* geom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
        geom->setDrawingMode(QSGGeometry::DrawLines);
        geom->setLineWidth(AXIS_WIDTH);

        QSGGeometry::Point2D* v = geom->vertexDataAsPoint2D();
        v[0].set(m_offsetX, originY);
        v[1].set(width(), originY);

        auto mat = new QSGFlatColorMaterial();
        mat->setColor(AXIS_COLOR);

        auto node = new QSGGeometryNode();
        node->setGeometry(geom);
        node->setFlag(QSGNode::OwnsGeometry);
        node->setMaterial(mat);
        node->setFlag(QSGNode::OwnsMaterial);
        root->appendChildNode(node);
    }

    // Y 轴（垂直）→ 修正：从底部到顶部
    {
        QSGGeometry* geom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
        geom->setDrawingMode(QSGGeometry::DrawLines);
        geom->setLineWidth(AXIS_WIDTH);

        QSGGeometry::Point2D* v = geom->vertexDataAsPoint2D();
        v[0].set(m_offsetX, height()); // 底部
        v[1].set(m_offsetX, 0);        // 顶部

        auto mat = new QSGFlatColorMaterial();
        mat->setColor(AXIS_COLOR);

        auto node = new QSGGeometryNode();
        node->setGeometry(geom);
        node->setFlag(QSGNode::OwnsGeometry);
        node->setMaterial(mat);
        node->setFlag(QSGNode::OwnsMaterial);
        root->appendChildNode(node);
    }

    return root;
}

// ==== 缩放和平移 ====
void LineChartItem::wheelEvent(QWheelEvent* ev) {
    const qreal factor = ev->angleDelta().y() > 0 ? 1.1 : 0.9;
    if (ev->modifiers() & Qt::ShiftModifier) {
        m_scaleY *= factor;
    } else {
        m_scaleX *= factor;
    }
    update();
    ev->accept();
}

void LineChartItem::mousePressEvent(QMouseEvent* ev) {
    if (ev->button() == Qt::LeftButton) {
        m_lastMousePos = ev->pos();

        // 点击显示最近点信息
        QPointF clickPos = ev->pos();
        QPointF closestPoint;
        qreal minDist = 1e10;

        for (const auto& series : m_series) {
            for (const auto& pt : series) {
                QPointF screenPt(pt.x() * m_scaleX + m_offsetX,
                                 height() - m_offsetY - pt.y() * m_scaleY);
                qreal dist = std::hypot(screenPt.x() - clickPos.x(), screenPt.y() - clickPos.y());
                if (dist < minDist) {
                    minDist = dist;
                    closestPoint = pt;
                }
            }
        }

        if (minDist < 5.0) { // 点击范围容差
            qDebug() << "点击点 XY:" << closestPoint;
        }

        ev->accept();
    }
}

void LineChartItem::mouseMoveEvent(QMouseEvent* ev) {
    if (ev->buttons() & Qt::LeftButton) {
        QPointF delta = ev->pos() - m_lastMousePos;

        m_offsetX += delta.x();
        m_offsetY -= delta.y(); // Y 方向反向

        m_lastMousePos = ev->pos();
        update();
        ev->accept();
    }
}
